package com.miao.im.support.handler;

import com.miao.im.common.annotation.MessageCommand;
import com.miao.im.common.enums.Command;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Auther: miaoguoxin
 * @Date: 2021/3/1 14:21
 * @Description:
 */
@Component
@Slf4j
public class MessageHandlerFactory implements InitializingBean {
    @Autowired
    private ApplicationContext applicationContext;

    public static final Map<Command, AbstractMessageHandler<?>> COMMANDS = new ConcurrentHashMap<>();

    public AbstractMessageHandler<?> createHandler(int commandType) {
        Command command = Command.getByCode(commandType);
        if (command == null) {
            throw new RuntimeException("无效命令");
        }
        AbstractMessageHandler<?> handler = COMMANDS.get(command);
        if (handler == null) {
            throw new RuntimeException("找不到处理类");
        }
        return handler;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, AbstractMessageHandler> handler = applicationContext.getBeansOfType(AbstractMessageHandler.class);
        for (AbstractMessageHandler<?> value : handler.values()) {
            MessageCommand command = value.getClass().getAnnotation(MessageCommand.class);
            if (command == null) {
                throw new RuntimeException("can not allowed empty command bean");
            }
            AbstractMessageHandler<?> old = COMMANDS.putIfAbsent(command.value(), value);
            if (old != null) {
                log.warn("the key [{}] has loaded which bean named [{}],but the new one [{}] putted again ",
                        command.value().getCode(), old.getClass().getSimpleName(), value.getClass().getSimpleName());
            }
        }
    }
}
